package com.chushouya.manager.service.api.impl;

import com.chushouya.common.applet.WxClient;
import com.chushouya.common.config.WxClerkLiteConfig;
import com.chushouya.common.config.WxOfficialConfig;
import com.chushouya.common.constant.PlatformTypeEnum;
import com.chushouya.common.wx.dto.OfficialUserInfo;
import com.general.framework.core.constant.Constants;
import com.general.framework.core.enums.ContextUserType;
import com.general.framework.core.enums.DelFlagEnum;
import com.general.framework.core.enums.StatusEnum;
import com.general.framework.core.exception.Ex;
import com.chushouya.manager.constants.ClerkStatusEnum;
import com.chushouya.manager.constants.ClerkUserTypeEnum;
import com.chushouya.manager.constants.ClerkWorkStatusEnum;
import com.chushouya.manager.dao.entity.ClerkEntity;
import com.chushouya.manager.dao.entity.UserEntity;
import com.chushouya.manager.dao.entity.UserExtendEntity;
import com.chushouya.manager.dao.repository.ClerkRepository;
import com.chushouya.manager.dao.repository.UserExtendRepository;
import com.chushouya.manager.dao.repository.UserRepository;
import com.chushouya.manager.dto.admin.clerk.ClerkInfoDTO;
import com.chushouya.manager.dto.admin.clerk.ClerkQuery;
import com.chushouya.manager.dto.admin.signin.ClerkSignInDTO;
import com.chushouya.manager.service.admin.LoginLogService;
import com.chushouya.manager.service.api.ClerkApiService;
import com.chushouya.manager.service.api.WebAppTokenService;
import com.general.framework.core.lang.Beans;
import com.general.framework.core.lang.Check;
import com.general.framework.core.lang.Dates;
import com.general.framework.core.lang.Strings;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 工程师接口服务
 */
@Service
@Slf4j
public class ClerkApiServiceImpl implements ClerkApiService {

    @Resource
    private WxClerkLiteConfig wxClerkLiteConfig;

    @Resource
    private WxOfficialConfig wxOfficialConfig;

    @Resource
    private ClerkRepository clerkRepository;

    @Resource
    private UserRepository userRepository;

    @Resource
    private UserExtendRepository userExtendRepository;

    @Resource
    private WebAppTokenService webAppTokenService;

//    @Resource
//    private SmsRpcApi smsRpcApi;

    @Resource
    private LoginLogService loginLogService;

//    @Resource
//    private ClerkService clerkService;

    @Override
    public ClerkInfoDTO getClerkInfo(Long clerkId) {
        final ClerkEntity clerk = clerkRepository.selectByPrimaryKey(clerkId);
        if (Objects.isNull(clerk)) {
            throw Ex.business("工程师不存在");
        }
        ClerkInfoDTO clerkInfo = Beans.copy(clerk, ClerkInfoDTO.class);
        final UserExtendEntity userExtend = userExtendRepository.selectByUserId(clerk.getUserId());
        if (Objects.nonNull(userExtend)) {
            clerkInfo.setNickName(userExtend.getNickName());
            clerkInfo.setAvatar(userExtend.getAvatar());
        }
        return clerkInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ClerkInfoDTO saveWxNickNameAndAvatar(Long clerkId, String nickName, String avatar) {
        final ClerkEntity clerk = clerkRepository.selectByPrimaryKey(clerkId);
        final UserExtendEntity userExtendEntity = userExtendRepository.selectByUserId(clerk.getUserId());
        UserExtendEntity update = new UserExtendEntity();
        update.setUserExtendId(userExtendEntity.getUserExtendId());
        update.setNickName(nickName);
        update.setAvatar(avatar);
        update.setUpdateTime(Dates.getTimeNow());
        userExtendRepository.updateByPrimaryKeySelective(update);
        final ClerkInfoDTO clerkInfo = this.getClerkInfo(clerkId);
        clerkInfo.setNickName(nickName);
        clerkInfo.setAvatar(avatar);
        return clerkInfo;
    }

    @Override
    public void editWorkStatus(Long clerkId, Integer workStatus) {

//        clerkService.editWorkStatus(clerkId, workStatus);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long signIn(ClerkSignInDTO signIn) {
        WxClient client = new WxClient(wxOfficialConfig.getAppId(), wxOfficialConfig.getAppSecret());
        final OfficialUserInfo officialUserInfo = client.jsCode2OfficialUserInfo(signIn.getAuthCode());
        final Date timeNow = Dates.getTimeNow();
        ClerkQuery query = new ClerkQuery();
        query.setClerkPhone(signIn.getClerkPhone());
        ClerkEntity clerkEntity = clerkRepository.selectOne(query);
        if (Objects.nonNull(clerkEntity)) {
            if (Objects.equals(clerkEntity.getStatus(), ClerkStatusEnum.auditing.value())) {
                throw Ex.business("您的注册信息已提交");
            }
            if (Objects.equals(clerkEntity.getStatus(), ClerkStatusEnum.disable.value())) {
                throw Ex.business("工程师账号已停用，请联系平台");
            }
            if (Objects.equals(clerkEntity.getStatus(), ClerkStatusEnum.enable.value())) {
                throw Ex.business("您已经是工程师，请勿重复提交");
            }
        }

        UserEntity userEntity = userRepository.selectByUserPhone(signIn.getClerkPhone());
        if (Objects.isNull(userEntity)) {
            userEntity = new UserEntity();
            userEntity.setUserName(signIn.getClerkName());
            userEntity.setUserPhone(signIn.getClerkPhone());
            userEntity.setUpdateTime(timeNow);
            userEntity.setCreateTime(timeNow);
            userEntity.setStatus(StatusEnum.normal.value());
            userRepository.insertSelective(userEntity);
        } else {
            UserEntity update = new UserEntity();
            update.setUserId(userEntity.getUserId());
            update.setUserName(signIn.getClerkName());
            update.setUserPhone(signIn.getClerkPhone());
            update.setUpdateTime(timeNow);
            userRepository.updateByPrimaryKeySelective(update);
        }

        UserExtendEntity userExtendEntity = userExtendRepository.selectByAppIdAndUserId(wxOfficialConfig.getAppId(), userEntity.getUserId());
        if (Objects.isNull(userExtendEntity)) {
            userExtendEntity = new UserExtendEntity();
            userExtendEntity.setUserId(userEntity.getUserId());
//            userExtendEntity.setOpenIdOfficial(officialUserInfo.getOpenId());
//            userExtendEntity.setUnionId(officialUserInfo.getUnionId());
            userExtendEntity.setOpenId(officialUserInfo.getOpenId());
            userExtendEntity.setAppId(wxOfficialConfig.getAppId());
            userExtendEntity.setUpdateTime(timeNow);
            userExtendEntity.setCreateTime(timeNow);
            userExtendRepository.insertSelective(userExtendEntity);
        } else {
            UserExtendEntity update = new UserExtendEntity();
            update.setUserExtendId(userExtendEntity.getUserExtendId());
            update.setUserId(userEntity.getUserId());
            userExtendEntity.setOpenId(officialUserInfo.getOpenId());
//            update.setUnionId(officialUserInfo.getUnionId());
            update.setUpdateTime(timeNow);
            userExtendRepository.updateByPrimaryKeySelective(update);
        }

        clerkEntity = new ClerkEntity();
        clerkEntity.setUserId(userEntity.getUserId());
        clerkEntity.setClerkName(signIn.getClerkName());
        clerkEntity.setClerkPhone(signIn.getClerkPhone());
        clerkEntity.setUserType(ClerkUserTypeEnum.CLERK.value());
        clerkEntity.setStatus(ClerkStatusEnum.auditing.value());
        clerkEntity.setWorkStatus(ClerkWorkStatusEnum.resting.value());
//        clerkEntity.setStopDispatchType(StopDispatchTypeEnum.none.value());
        clerkEntity.setDelFlag(DelFlagEnum.normal.getValue());
        clerkEntity.setCreateTime(timeNow);
        clerkEntity.setUpdateTime(timeNow);
        clerkRepository.insertSelective(clerkEntity);

        return clerkEntity.getClerkId();
    }


    @Override
    public String getLiteOpenId(String code) {
        WxClient client = new WxClient(wxClerkLiteConfig.getAppId(), wxClerkLiteConfig.getAppSecret());
        return client.jscode2session(code);
    }

    @Override
    public void doPhoneLoginHandler(String phone) {
        ClerkQuery query = new ClerkQuery();
        query.setClerkPhone(phone);
        final ClerkEntity clerkEntity = clerkRepository.selectOne(query);
        Check.notNull(clerkEntity, "手机号{}未注册工程师", phone);

        if (Objects.equals(clerkEntity.getStatus(), ClerkStatusEnum.auditing.value())) {
            this.loginLogService.saveLoginLog(ContextUserType.APP_CLERK, clerkEntity.getClerkName(), Constants.LOGIN_FAIL, Strings.format("工程师信息审核中({})", PlatformTypeEnum.WEIXIN.value()));
            throw Ex.business("工程师信息审核中，请联系平台");
        }
        if (Objects.equals(clerkEntity.getStatus(), ClerkStatusEnum.disable.value())) {
            this.loginLogService.saveLoginLog(ContextUserType.APP_CLERK, clerkEntity.getClerkName(), Constants.LOGIN_FAIL, Strings.format("工程师账号已停用({})", PlatformTypeEnum.WEIXIN.value()));
            throw Ex.business("登录失败，工程师账号已停用");
        }

        final UserEntity userEntity = userRepository.selectByPrimaryKey(clerkEntity.getUserId());
        Check.notNull(userEntity, "工程师不存在,请联系管理员:{}", phone);
    }

    @Override
    public List<ClerkEntity> getAllClerkList() {
        List<ClerkEntity> clerkList = clerkRepository.selectAll();
        return clerkList;
    }

}
